package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.Menu;
import com.example.entity.RoleMenu;
import com.example.service.MenuService;
import com.example.mapper.MenuMapper;
import com.example.service.RoleMenuService;
import com.example.utils.BeanCopyUtils;
import com.example.utils.ResponseResult;
import com.example.utils.SecurityUtils;
import com.example.utils.SystemConstants;
import com.example.vo.MenuCheckedVo;
import com.example.vo.MenuTreeVo;
import com.example.vo.MenuVo;
import com.example.vo.PageVo;
import com.qiniu.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;

/**
* @author sprite-pc
* @description 针对表【sys_menu(菜单权限表)】的数据库操作Service实现
* @createDate 2023-12-29 12:57:47
*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService{

    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public List<String> selectPermsByUserId(Long id) {
        //如果是管理员，返回所有的权限
        if(id == 1L){
            LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.BUTTON);
            wrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            List<Menu> menus = list(wrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        //否则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<MenuVo> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if(SecurityUtils.isAdmin()){
            //如果是 获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        }else{
            //否则  获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus,MenuVo.class);
        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<MenuVo> menuTree = builderMenuTree(menuVos,0L);
        return menuTree;
    }


    @Override
    public ResponseResult roleMenuTreeselect(Long roleId) {
//        MenuCheckedVo menuCheckedVo = new MenuCheckedVo();
//        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(RoleMenu::getRoleId,roleId);
//        List<RoleMenu> roleMenus = roleMenuService.list(queryWrapper);
//        List<String> checkedKeys = roleMenus.stream().map(roleMenu -> {
//            return roleMenu.getMenuId().toString();
//        }).collect(Collectors.toList());
//        menuCheckedVo.setCheckedKeys(checkedKeys);
//
//        List<Menu> menus = list();
//
//        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus,MenuVo.class);
//        //构建tree
//        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
//        List<MenuVo> menuTree = builderMenuTree(menuVos,0L);
//        menuCheckedVo.setMenus(menuTree);
//
//        return ResponseResult.okResult(menuCheckedVo);
        //先从role_menu表中找到关系
        LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper();
        wrapper.eq(RoleMenu::getRoleId,roleId);
        List<RoleMenu> MenuList = roleMenuService.list(wrapper);
        //根据MenuId找到menu信息
        List<Menu> Menu = MenuList.stream().map(m -> getById(m.getMenuId()))
                .collect(Collectors.toList());
        //转为要求响应实体
        List<MenuTreeVo> menuTreeVos = BeanCopyUtils.copyBeanList(Menu, MenuTreeVo.class);
        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<MenuTreeVo> menuTree = builderMenuTree2(menuTreeVos,0L);
        return ResponseResult.okResult(menuTree);
    }

    @Override
    public ResponseResult getList(String menuName, String status) {
        LambdaQueryWrapper<Menu> queryWrapper =new LambdaQueryWrapper<>();
        if (!StringUtils.isNullOrEmpty(menuName)){
            queryWrapper.like(Menu::getMenuName,menuName);
        }
        if (!StringUtils.isNullOrEmpty(status)){
            queryWrapper.eq(Menu::getStatus,status);
        }
        queryWrapper.orderByAsc(Menu::getOrderNum);
        List<Menu> menus = list(queryWrapper);
        return ResponseResult.okResult(menus);

    }

    @Override
    public ResponseResult deleteMenus(Long id) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId,id);
        remove(queryWrapper);
        removeById(id);
        return ResponseResult.okResult();
    }

    private List<MenuVo> builderMenuTree(List<MenuVo> menus, Long parentId) {
        List<MenuVo> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    private List<MenuVo> getChildren(MenuVo menu, List<MenuVo> menus) {
        List<MenuVo> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m->m.setChildren(getChildren(m,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }

    private List<MenuTreeVo> builderMenuTree2(List<MenuTreeVo> menus, Long parentId) {
        List<MenuTreeVo> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren2(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    //递归：获取传入参数的子Meun
    private List<MenuTreeVo> getChildren2(MenuTreeVo menu, List<MenuTreeVo> menus) {
        List<MenuTreeVo> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m->m.setChildren(getChildren2(m,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }

}




